MapStruct একটি Java annotation processor যা ডোমেইন অবজেক্ট এবং DTO (Data Transfer Object) এর মধ্যে অটোমেটিকভাবে ম্যাপিং করতে সহায়তা করে। এতে Mapping Methods তৈরি করতে হয়, যা ডেটা এক অবজেক্ট থেকে অন্য অবজেক্টে কপি করে। MapStruct compile-time এ কোড জেনারেট করে, ফলে পারফরম্যান্সে কোনো সমস্যা হয় না। এটি বিশেষত JavaBeans (POJOs) বা ডোমেইন অবজেক্টের মধ্যে ম্যাপিং করার জন্য উপকারী।
এই টিউটোরিয়ালে, আমরা উদাহরণ সহ দেখব কীভাবে MapStruct এর মাধ্যমে Mapping Methods তৈরি করা যায়।
১. MapStruct Mapping Methods তৈরি করা
MapStruct এর মূল কাজ হল ডোমেইন অবজেক্ট এবং DTO (Data Transfer Object) এর মধ্যে ম্যাপিং করা। এজন্য MapStruct এ একটি Mapper Interface তৈরি করতে হয়, এবং এই ইন্টারফেসে ম্যাপিং মেথডগুলির সিগনেচার থাকে। MapStruct সেই মেথডগুলোর জন্য কোড জেনারেট করে।
উদাহরণ: Mapping Methods তৈরি
ধরা যাক, আমাদের দুটি ক্লাস Employee এবং EmployeeDTO রয়েছে, এবং আমরা এই দুই ক্লাসের মধ্যে ম্যাপিং করতে চাই।
১.১ Employee (Domain Object)
public class Employee {
private String name;
private String department;
private int age;
// Constructors, Getters, and Setters
public Employee(String name, String department, int age) {
this.name = name;
this.department = department;
this.age = age;
}
// Getters and Setters
}
1.2 EmployeeDTO (Data Transfer Object)
public class EmployeeDTO {
private String fullName;
private String department;
private int age;
// Constructors, Getters, and Setters
public EmployeeDTO(String fullName, String department, int age) {
this.fullName = fullName;
this.department = department;
this.age = age;
}
// Getters and Setters
}
এখন, আমাদের Employee ক্লাসের ডেটা EmployeeDTO ক্লাসে ম্যাপ করতে হবে।
1.3 EmployeeMapper (Mapper Interface)
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface EmployeeMapper {
EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);
// Mapping method
EmployeeDTO employeeToEmployeeDTO(Employee employee);
}
এখানে, EmployeeMapper একটি Mapper Interface যা employeeToEmployeeDTO মেথডের মাধ্যমে Employee অবজেক্টকে EmployeeDTO অবজেক্টে ম্যাপ করবে।
1.4 Main Class (Usage)
public class Main {
public static void main(String[] args) {
Employee employee = new Employee("John Doe", "Engineering", 30);
// Mapping
EmployeeDTO employeeDTO = EmployeeMapper.INSTANCE.employeeToEmployeeDTO(employee);
System.out.println("Full Name: " + employeeDTO.getFullName());
System.out.println("Department: " + employeeDTO.getDepartment());
System.out.println("Age: " + employeeDTO.getAge());
}
}
এখানে, EmployeeMapper.INSTANCE.employeeToEmployeeDTO(employee) এর মাধ্যমে Employee অবজেক্টটি EmployeeDTO তে ম্যাপ হয়ে যায়।
এটি কম্পাইল টাইমে ম্যাপিং কোড জেনারেট করবে এবং আপনাকে রানটাইমে কোনো কাস্টম কোড লেখার প্রয়োজন হবে না।
২. MapStruct Mapping Methods এর বিভিন্ন ধরণ
MapStruct এর মাধ্যমে Mapping Methods তৈরি করতে আপনি বিভিন্ন কাস্টম ম্যাপিং লজিক বা কনভার্সন যুক্ত করতে পারেন। এটি সুনির্দিষ্ট ম্যাপিং প্রক্রিয়া তৈরি করতে সহায়তা করে।
২.১ Custom Mapping for Specific Fields
ধরা যাক, আমাদের Employee এবং EmployeeDTO ক্লাসের মধ্যে name এবং fullName ফিল্ডের নাম ভিন্ন, তাহলে আমরা কাস্টম ম্যাপিং করতে পারি।
@Mapper
public interface EmployeeMapper {
EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);
@Mapping(source = "name", target = "fullName")
EmployeeDTO employeeToEmployeeDTO(Employee employee);
}
এখানে, @Mapping অ্যানোটেশন ব্যবহার করে Employee এর name ফিল্ডকে EmployeeDTO এর fullName ফিল্ডে ম্যাপ করা হয়েছে।
২.২ Mapping Collections
MapStruct এর মাধ্যমে আপনি একটি লিস্ট বা অ্যারে থেকেও ম্যাপিং করতে পারবেন। এখানে একটি উদাহরণ:
@Mapper
public interface EmployeeMapper {
EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);
List<EmployeeDTO> employeesToEmployeeDTOs(List<Employee> employees);
}
এখানে, employeesToEmployeeDTOs মেথডটি একটি List কে List তে রূপান্তরিত করবে।
৩. MapStruct এর মাধ্যমে Complex Mapping
আপনি যদি আরও জটিল ম্যাপিং করতে চান, যেখানে বিভিন্ন ক্লাসের মধ্যে ম্যাপিং করা হয়, তাহলে MapStruct সহজেই তা সমাধান করতে পারে।
৩.১ Mapping Nested Objects
ধরা যাক, আমাদের Employee এবং Department নামে দুটি ক্লাস রয়েছে, এবং Employee ক্লাসে Department অবজেক্ট রয়েছে। আমাদের EmployeeDTO তে এই Department ক্লাসটিও ম্যাপ করতে হবে।
Example: Nested Object Mapping
public class Department {
private String departmentName;
// Getters and Setters
}
public class Employee {
private String name;
private Department department;
// Getters and Setters
}
এখন, Department কে EmployeeDTO তে ম্যাপ করতে আমরা কাস্টম ম্যাপিং ব্যবহার করতে পারি।
@Mapper
public interface EmployeeMapper {
EmployeeDTO employeeToEmployeeDTO(Employee employee);
// Mapping Department to DepartmentDTO
DepartmentDTO departmentToDepartmentDTO(Department department);
}
এখানে, আমরা Department ক্লাসের ম্যাপিংয়ের জন্য departmentToDepartmentDTO মেথড তৈরি করেছি, যা DepartmentDTO তে ডেটা কপি করবে।
৪. Default and Custom Mapping Methods
MapStruct ডিফল্ট ম্যাপিং পদ্ধতি যেমন ফিল্ড নামের ভিত্তিতে অটোমেটিক ম্যাপিং করার জন্য পরিচিত। কিন্তু আপনি যখন কাস্টম ম্যাপিং চাহিদা প্রয়োগ করবেন, তখন custom mapping methods তৈরি করতে হবে। এই কাস্টম মেথডের মাধ্যমে আপনি ডেটা কনভার্সন বা লজিক প্রয়োগ করতে পারবেন।
Example: Custom Mapping Method
@Mapper
public interface EmployeeMapper {
@Mapping(target = "fullName", expression = "java(employee.getName() + \" - \" + employee.getDepartment())")
EmployeeDTO employeeToEmployeeDTO(Employee employee);
}
এখানে, expression এর মাধ্যমে কাস্টম ম্যাপিং করা হয়েছে, যেখানে fullName ফিল্ডে name এবং department ফিল্ডের মান একসাথে যোগ করা হয়েছে।
সারাংশ
MapStruct একটি শক্তিশালী টুল যা ডোমেইন অবজেক্ট এবং DTO (Data Transfer Object) এর মধ্যে ডেটা ম্যাপিং করতে সাহায্য করে। এটি compile-time এ কোড জেনারেট করে, ফলে রানটাইম পারফরম্যান্সের কোন প্রভাব পড়ে না। Mapping Methods তৈরি করার সময়, আপনি বিভিন্ন কাস্টম এবং ডিফল্ট ম্যাপিং পদ্ধতি ব্যবহার করতে পারেন, যেমন nested object mapping, custom mapping এবং collections mapping। MapStruct ব্যবহারে কোড লেখার প্রক্রিয়া অনেক সহজ হয়ে ওঠে এবং এটি আপনার ডেভেলপমেন্ট সাইকেলকে দ্রুততর করে।
Read more